package com.peaksport.framework.extend.schedule;

import java.util.Date;
import java.util.List;

import javax.transaction.Transactional;
import javax.transaction.Transactional.TxType;

import org.aspectj.apache.bcel.generic.IINC;
import org.springframework.stereotype.Service;

import com.peaksport.framework.base.dao.IBaseDAO;
import com.peaksport.framework.base.service.CoreBaseService;
import com.peaksport.framework.extend.spring.PKApplicationContext;
import com.peaksport.framework.util.PKPublicUtils;
import com.peaksport.pkms.system.entity.ScheduleDefEntity;
import com.peaksport.pkms.system.entity.ScheduleInstEntity;
import com.peaksport.pkms.system.venum.ScheduleDefStatusEnum;
import com.peaksport.pkms.system.venum.ScheduleStatusEnum;

@Service
public class PKScheduleService extends CoreBaseService {
	
	/**
	 * 根据状态获取定义的后台事务
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<ScheduleDefEntity> getScheduleDefColByStatus(ScheduleDefStatusEnum status) {
		String sql = "select FID,FNumber,FName,FRunnableClass,FCron,FMicroService,FIsMutex from CT_Task_ScheduleDef ";
		if(status != null) sql = sql + " where FStatus=" + status.getValue();
		List<ScheduleDefEntity> lstScheduleDef = (List<ScheduleDefEntity>) queryRecordForNative(sql, ScheduleDefEntity.class);
		return lstScheduleDef;
	}
	
	/**
	 * 添加定义后台事务
	 * @param number
	 * @param name
	 * @param runnableClass
	 * @param cron
	 * @param desc
	 * @param microSystem
	 * @return
	 */
	@Transactional
	public ScheduleDefEntity addNewScheduleDef(String number,String name,String runnableClass, String cron, String desc, String microService, boolean isMutex) {
		ScheduleDefEntity scheduleDefEntity = new ScheduleDefEntity();
		scheduleDefEntity.setNumber(number);
		scheduleDefEntity.setName(name);
		scheduleDefEntity.setRunnableClass(runnableClass);
		scheduleDefEntity.setCron(cron);
		scheduleDefEntity.setDesc(desc);
		scheduleDefEntity.setMicroService(microService);
		scheduleDefEntity.setMutex(isMutex);
		scheduleDefEntity.setStatus(ScheduleDefStatusEnum.SAVE);
		save(scheduleDefEntity);
		return scheduleDefEntity;
	}
	
	/**
	 * 更新后台事务状态
	 * @param pk
	 * @param statusEnum
	 */
	@Transactional
	public void updateScheduleDefStatus(String pk,ScheduleDefStatusEnum statusEnum) {
		String sql = String.format("update ct_task_scheduledef set FStatus=%d where FID='%s'",statusEnum.getValue(),pk);
		executeSqlForNative(sql);
	}
	
	/**
	 * 检查后台事务是否运行中,默认时同一后台事务定义只允许在一个微服务实例中运行
	 * 若运行并行运行与多个服务间,赋予一唯一的assistKey
	 * @param scheduleDefEntity
	 * @return
	 */
	public boolean isRunning(ScheduleDefEntity scheduleDefEntity) {
		verifyDevNull(scheduleDefEntity, "scheduleDefEntity不能为空");
		String sql = String.format("select 1 from ct_task_scheduleInst where FScheduleDefID='%s' and FStatus='%s'", 
				scheduleDefEntity.getId(),ScheduleStatusEnum.RUNNING);
		String assistKey = (String) scheduleDefEntity.getExtendValue().get("assisKey");
		if (!PKPublicUtils.isEmpty(assistKey)) {
			sql = sql + " and FAssistKey='" + assistKey + "'";
		}
		boolean b = isExistsForNative(sql);
		return b;
	}
	
	/**
	 * 新增后台事务实例
	 * @param scheduleDefEntity
	 * @return
	 */
	@Transactional(value=TxType.REQUIRES_NEW)
	public ScheduleInstEntity addNewScheduleInst(ScheduleDefEntity scheduleDefEntity) {
		Date now = getCurrentTime();
		ScheduleInstEntity scheduleInstEntity = new ScheduleInstEntity();
		scheduleInstEntity.setTitle(scheduleDefEntity.getName()+ " -- " +  now.getTime());
		scheduleInstEntity.setScheduleDefEntity(scheduleDefEntity);
		scheduleInstEntity.setStartTime(now);
		scheduleInstEntity.setStatus(ScheduleStatusEnum.RUNNING);
		//服务运行机器 pkms-permit@192.168.128.4:9001
		String instInServer = PKApplicationContext.getMicroService() + "@" + PKApplicationContext.getHostIP() + ":" + PKApplicationContext.getPort();
		scheduleInstEntity.setInstInServer(instInServer);
		String assistKey = (String) scheduleDefEntity.getExtendValue().get("assisKey");
		if (!PKPublicUtils.isEmpty(assistKey)) {
			scheduleInstEntity.setAssistKey(assistKey);
		}
		save(scheduleInstEntity);
		return scheduleInstEntity;
	}
	/**
	 * 更新后台事务实例
	 * @param scheduleInstEntity
	 */
	@Transactional(value=TxType.REQUIRES_NEW)
	public void updateScheduleInst(ScheduleInstEntity scheduleInstEntity) {
		save(scheduleInstEntity);
	}
	
	/**
	 * 删除后台事务定义
	 * 删除逻辑：
	 * 	1. 如果不存在后台事务实例直接删除
	 *  2. 存在后台事务实例则设置为“已删除”状态
	 * @param pk
	 */
	@Transactional
	public void removeScheduleDef(String pk) {
		//是否存在后台事务实例
		String sqlExistsInst = String.format("select 1 from ct_task_scheduleinst where FScheduleDefId='%s'",pk);
		boolean isExistsInst = isExistsForNative(sqlExistsInst);
		if (isExistsInst) {
			updateScheduleDefStatus(pk,ScheduleDefStatusEnum.DELETE);
		} else {
			delete(pk);
		}
		
		
	}
	
	public void removeScheduleInst(List<String> listPK) {
		
	}
	public void clearScheduleInst(String scheduleDefPK) {
		
	}
	
	@Override
	public IBaseDAO<?> getDAO() {
		return null;
	}

	
	
	
}
